import {
  h,
  ref,
  PropType,
  computed,
  onUnmounted,
  defineComponent,
  resolveComponent,
} from 'vue';
import { useClickOutside, useNamespace } from '@ibiz-template/vue3-util';
import { OnClickOutsideResult, eventPath } from '@ibiz-template/core';
import { GridFieldColumnController } from '../../controller';
import './grid-column-header.scss';

export const IBizGridColumnHeader = defineComponent({
  name: 'IBizGridColumnHeader',
  props: {
    controller: {
      type: Object as PropType<GridFieldColumnController>,
      required: true,
    },
    column: {
      type: Object as PropType<IData>,
      required: true,
    },
  },
  setup(props) {
    const ns = useNamespace('grid-column-header');
    const c = props.controller;
    const visible = ref(false);
    const content = ref();

    const value = computed(() => {
      return c.grid.state.columnFilter[c.filterName];
    });

    const required = computed(() => {
      return (c as IData).editItem
        ? (c as IData).editItem.allowEmpty !== true
        : false;
    });

    let funcs: OnClickOutsideResult | undefined;

    const onShow = (): void => {
      if (funcs) {
        return funcs.proceed();
      }
      funcs = useClickOutside(content, evt => {
        const classList: string[] = [];
        eventPath(evt).forEach(e => {
          if (e && (e as IData).classList) {
            classList.push(...(e as IData).classList);
          }
        });
        if (classList.includes('el-popper')) return;
        visible.value = false;
      });
    };

    /**
     * 隐藏时停止监听
     *
     */
    const onHide = (): void => {
      funcs?.pause();
    };

    const onClick = (e: MouseEvent): void => {
      e.stopPropagation();
      visible.value = true;
    };

    /**
     * 筛选值改变
     *
     * @param {unknown} val
     * @param {string} [_name]
     */
    const onChange = (val: unknown, _name?: string): void => {
      c.setFilterValue(val);
    };

    /**
     * 筛选
     *
     */
    const onScreen = (): void => {
      visible.value = false;
      c.grid.load({
        isInitialLoad:
          c.grid.model.pagingMode === 2 || c.grid.model.pagingMode === 3,
      });
    };

    /**
     * 重置
     *
     */
    const onReset = (): void => {
      c.setFilterValue(undefined);
      onScreen();
    };

    onUnmounted(() => {
      funcs?.stop();
    });

    return {
      c,
      ns,
      value,
      visible,
      content,
      required,
      onShow,
      onHide,
      onClick,
      onChange,
      onScreen,
      onReset,
    };
  },
  render() {
    return (
      <div class={this.ns.b()}>
        <div class={this.ns.e('caption')}>
          {this.required && (
            <span class={this.ns.em('caption', 'required')}>*</span>
          )}
          {this.c.model.caption}
        </div>
        {this.c.filterEditorProvider && (
          <el-popover
            width={220}
            onShow={this.onShow}
            onHide={this.onHide}
            visible={this.visible}
            popper-class={this.ns.em('filter', 'popover')}
          >
            {{
              reference: () => {
                return (
                  <ion-icon
                    name='funnel'
                    class={[
                      this.ns.em('filter', 'icon'),
                      this.ns.is('active', !!this.value),
                    ]}
                    title='筛选'
                    onClick={this.onClick}
                  ></ion-icon>
                );
              },
              default: () => {
                return (
                  <div ref='content' class={this.ns.em('filter', 'content')}>
                    <div class={this.ns.em('filter', 'editor')}>
                      {h(
                        resolveComponent(
                          this.c.filterEditorProvider!.gridEditor,
                        ),
                        {
                          data: {},
                          autoFocus: true,
                          value: this.value,
                          onChange: this.onChange,
                          controller: this.c.filterEditor,
                        },
                      )}
                    </div>
                    <div class={this.ns.em('filter', 'bottom')}>
                      <el-button type='text' onClick={this.onScreen}>
                        筛选
                      </el-button>
                      <el-button type='text' onClick={this.onReset}>
                        重置
                      </el-button>
                    </div>
                  </div>
                );
              },
            }}
          </el-popover>
        )}
      </div>
    );
  },
});
